package com.guoji.cameracall.surface

import android.content.Context
import android.hardware.Camera
import android.util.AttributeSet
import android.util.Log
import android.view.SurfaceHolder
import android.view.SurfaceView
import com.guoji.cameracall.helper.EncodePushH265
import com.guoji.cameracall.helper.YuvUtil
import com.guoji.cameracall.socket.ISocketLive

/**
 * create by zhongZihao on 2021/9/24
 */
class CameraSurface @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : SurfaceView(context, attrs, defStyleAttr), SurfaceHolder.Callback, Camera.PreviewCallback {
    private var mCamera: Camera? = null
    private var encoder: EncodePushH265? = null
    private var size: Camera.Size? = null


    init {
        holder.addCallback(this)
    }

    override fun surfaceCreated(holder: SurfaceHolder?) {
        startPreview()
    }

    override fun surfaceChanged(holder: SurfaceHolder?, format: Int, width: Int, height: Int) {
    }

    override fun surfaceDestroyed(holder: SurfaceHolder?) {
        //mCamera?.stopPreview()
        mCamera?.release()
    }

    private var buffer: ByteArray? = null

    private fun startPreview() {
        mCamera = Camera.open()
        size = mCamera!!.parameters.previewSize
        buffer = ByteArray(size!!.width * size!!.height * 3 / 2)
        Log.d("TAG_CameraSurface", "mCamera size:${size!!.width}*${size!!.height}")
        try {
            mCamera!!.apply {
                setPreviewDisplay(holder)
                setDisplayOrientation(90)
                addCallbackBuffer(buffer)
                setPreviewCallbackWithBuffer(this@CameraSurface)
                startPreview()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

    }

    override fun onPreviewFrame(data: ByteArray?, camera: Camera?) {
        data ?: return
        Log.d("TAG_CameraSurface", "local onPreviewFrame...${data.size}")
        if (isCaptrue) {
            //拍照逻辑
            isCaptrue = false
            val nv21 = ByteArray(data.size)
            //旋转YUV
            YuvUtil.portraitData2Raw(data, nv21, size!!.width, size!!.height)
            //旋转后保存应该预览的宽高对换
            YuvUtil.captrue(nv21, size!!.height, size!!.width)
        }
        encoder?.encodeCameraFrame(data)
        mCamera?.addCallbackBuffer(data)

    }

    private var isCaptrue = false

    fun startCaptrue() {
        isCaptrue = true
    }


    fun startEncoder(iSocketLive: ISocketLive) {
        //注意旋转后的宽高对换
        encoder = EncodePushH265(
            iSocketLive,
            size!!.width,
            size!!.height
        )
        encoder!!.startEncode()
    }
}